package com.echo.yixiaowu.feature.components

import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.LocalOverscrollFactory
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil3.ImageLoader
import coil3.compose.AsyncImage
import com.echo.yixiaowu.R
import com.echo.yixiaowu.feature.main.home.DraggableItem
import com.echo.yixiaowu.feature.main.home.HomeEvent
import com.echo.yixiaowu.feature.main.home.RecommendState
import com.echo.yixiaowu.feature.main.home.tab.RecommendTab
import com.echo.yixiaowu.layout.XiaowuRow
import com.echo.yixiaowu.main.CarouselImage
import com.echo.yixiaowu.main.page.OneContentPage
import com.echo.yixiaowu.main.page.home.rememberCollapsingToolbarState
import com.echo.yixiaowu.route.AppRoute
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch

val rowList: List<HomeFuncItem> = listOf(
    HomeFuncItem(1, "版本咨询", R.drawable.icon1),
    HomeFuncItem(2, "养成计算器", R.drawable.icon2),
    HomeFuncItem(3, "签到简历", R.drawable.icon3),
    HomeFuncItem(4, "WIKI", R.drawable.icon4),
    HomeFuncItem(5, "大地图", R.drawable.icon5),
    HomeFuncItem(6, "回归邀约", R.drawable.icon6),
    HomeFuncItem(7, "鸣潮周边", R.drawable.merchandise),
)

data class HomeFuncItem(val id: Int, val title: String, val icon: Int)

/**
 * 单个分类页面，包含一个LazyColumn，负责内部所有元素的展示和滚动逻辑
 */
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun CategoryPage(
    pageData: DraggableItem,
    recommendState: RecommendState,
    listState: LazyListState,
    innerGridStateList: MutableMap<Int, List<LazyStaggeredGridState>>,
    initialHeaderHeight: Dp,
    mFirstMenuHeight: Dp,
    mStickyHeaderHeight: Dp,
    onEvent: (HomeEvent) -> Unit,
    sharedTransitionScope: SharedTransitionScope,
    animatedVisibilityScope: AnimatedVisibilityScope,
    imageLoader: ImageLoader,
    pageId: Int,
    onNavigate: (AppRoute) -> Unit,
) {
    val density = LocalDensity.current
    val coroutineScope = rememberCoroutineScope()
    var userScrollEnabled by remember { mutableStateOf(true) }
    var isScrollAutomatically by remember { mutableStateOf(false) }
    val detailHeight = 780.dp

    val secondTabs = pageData.tabs
    val secondTitlePagerState =
        rememberPagerState(initialPage = pageData.tabSelectedPage, pageCount = { secondTabs.size })
    val innerGridState =
        innerGridStateList[pageData.id]

    // 判断二级Tab是否吸顶
    val isSticky by remember {
        derivedStateOf {
            val stickyHeaderItemInfo = listState.layoutInfo.visibleItemsInfo.find { it.index == 2 }

            if (stickyHeaderItemInfo != null) {
                // 如果 header 在可见项中，当它的顶部位于或超出视口顶部时，它就是 sticky 的。
                stickyHeaderItemInfo.offset < -with(density) { mFirstMenuHeight.toPx() }
            } else {
                // 检查当前第一个可见项的索引是否大于 header 的索引。
                listState.firstVisibleItemIndex > 2
            }
        }
    }

    val toolbarState = rememberCollapsingToolbarState(
        listState = listState,
        headerHeight = initialHeaderHeight,
    )
    LaunchedEffect(secondTitlePagerState) {
        snapshotFlow { secondTitlePagerState.currentPage }.distinctUntilChanged()
            .collect { index -> onEvent(HomeEvent.OnTabSelected(pageId, index)) }
    }

    val stickyAnimatedCornerRadius by animateDpAsState(
        targetValue = if (isSticky) 0.dp else 10.dp, label = "stickyAnimatedCornerRadius"
    )
    Box(modifier = Modifier.fillMaxSize()) {
        // 可滚动内容
        CompositionLocalProvider(LocalOverscrollFactory provides null) {
            LazyColumn(
                state = listState,
                modifier = Modifier.fillMaxSize(),
                contentPadding = PaddingValues(top = initialHeaderHeight)
            ) {
                item { CarouselImage(userScrollEnabled) }

                item {
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(vertical = 16.dp)
                            .horizontalScroll(rememberScrollState()),
                        verticalAlignment = Alignment.CenterVertically,
                    ) {
                        rowList.forEachIndexed { _, item ->
                            RowListItem(
                                imageLoader, item.title, item.icon
                            )
                        }
                    }
                }

                stickyHeader {
                    XiaowuRow(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(mStickyHeaderHeight)
                            .clip(
                                RoundedCornerShape(
                                    topStart = stickyAnimatedCornerRadius,
                                    topEnd = stickyAnimatedCornerRadius
                                )
                            )
                            .border(
                                width = 1.dp,
                                color = Color.LightGray.copy(alpha = 0.3f),
                                shape = RoundedCornerShape(
                                    topStart = stickyAnimatedCornerRadius,
                                    topEnd = stickyAnimatedCornerRadius
                                )
                            ),
                        titleList = secondTabs,
                        state = secondTitlePagerState,
                        scope = coroutineScope,
                        pageId = pageId,
                        onEvent = onEvent
                    )
                }

                item {
                    HorizontalPager(modifier = Modifier
                        .fillMaxWidth()
                        .height(detailHeight)
                        .padding(bottom = 58.dp)
                        .clipToBounds(),
                        state = secondTitlePagerState,
                        userScrollEnabled = userScrollEnabled,
                        key = { tabPage -> secondTabs[tabPage].id }) { tabPage ->
                        // 滚动逻辑
                        val currentGridState = innerGridState!![tabPage]
                        val gridScrollConnection = rememberGridNestedScrollConnection(
                            listState, currentGridState, isSticky, coroutineScope
                        )
                        // 页面是否显示在最顶部
                        val isAtTop by remember {
                            derivedStateOf {
                                listState.firstVisibleItemIndex == 0 && listState.firstVisibleItemScrollOffset == 0
                            }
                        }
                        // 列表滚动停止时，自动吸附效果
                        LaunchedEffect(
                            listState.isScrollInProgress,
                            currentGridState.isScrollInProgress
                        ) {
                            val isScrolling =
                                listState.isScrollInProgress || currentGridState.isScrollInProgress
                            userScrollEnabled = !isScrolling

                            if (!isScrolling && !isScrollAutomatically && listState.firstVisibleItemIndex == 0) {
                                val menuHeightPx =
                                    with(density) { mFirstMenuHeight.roundToPx() }
                                val thresholdPx = menuHeightPx / 2
                                val currentOffset = listState.firstVisibleItemScrollOffset

                                if (currentOffset in 1..<menuHeightPx) {
                                    val targetOffset =
                                        if (currentOffset > thresholdPx) menuHeightPx else 0
                                    isScrollAutomatically = true
                                    coroutineScope.launch {
                                        listState.animateScrollToItem(0, targetOffset)
                                    }.invokeOnCompletion {
                                        isScrollAutomatically = false
                                    }
                                }
                            }
                        }
                        LaunchedEffect(tabPage) {
                            onEvent(
                                HomeEvent.OnLoadTabData(
                                    1,
                                    secondTabs[tabPage].id,
                                    false
                                )
                            )
                        }
                        SmartSwipeRefresh(
                            enable = isAtTop,
                            onRefresh = {
                                onEvent(
                                    HomeEvent.OnLoadTabData(
                                        1,
                                        secondTabs[tabPage].id,
                                        true
                                    )
                                )
                            }) {
                            when (tabPage) {
                                0 -> OneContentPage(
                                    gridState = currentGridState,
                                    modifier = Modifier
                                        .fillMaxSize()
                                        .nestedScroll(gridScrollConnection),
                                    imageLoader = imageLoader,
                                    onNavigate = onNavigate
                                )

                                1 -> RecommendTab(
                                    gridState = currentGridState,
                                    recommendState = recommendState,
                                    modifier = Modifier
                                        .fillMaxSize()
                                        .nestedScroll(gridScrollConnection),
                                    sharedTransitionScope = sharedTransitionScope,
                                    animatedVisibilityScope = animatedVisibilityScope,
                                    onNavigate = onNavigate,
                                    onRefresh = {
                                        onEvent(
                                            HomeEvent.OnLoadTabData(
                                                1,
                                                secondTabs[tabPage].id,
                                                true
                                            )
                                        )
                                    }
                                )

                                else -> Text(
                                    text = "Page Content for ${secondTabs[tabPage].title}",
                                    modifier = Modifier.fillMaxWidth()
                                )
                            }
                        }
                    }
                }
            }
        }
        // 背景，可替换为图片
        Box(modifier = Modifier
            .fillMaxWidth()
            .height(initialHeaderHeight)
            .graphicsLayer {
                translationY = toolbarState.headerOffset
            }
            .background(colorResource(pageData.background)))
    }
}

@Composable
fun RowListItem(imageLoader: ImageLoader, title: String, icon: Int) {
    Column(
        modifier = Modifier
            .width(75.dp)
            .clickable(onClick = { /*todo 点击逻辑 */ },
                indication = null,
                interactionSource = remember { MutableInteractionSource() }),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(5.dp)
    ) {
        AsyncImage(
            imageLoader = imageLoader,
            model = icon,
            contentDescription = "description $title",
            modifier = Modifier.size(38.dp),
            contentScale = ContentScale.Crop,
        )
        Text(
            text = title,
            fontSize = 12.sp,
            color = Color.Black,
            maxLines = 1,
        )
    }
}